using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Evolution.Engine.Managers;

namespace Evolution.Engine.Objects
{
    public class Texture2d
    {
        protected string _Asset;
        protected string _DisplacementAsset;
        protected Texture2D _Texture;
        protected Texture2D _DisplacementTexture;
        protected SpriteBatch _SpriteBatch;
        protected EffectTypes _EffectType;
        protected Vector2 _Position;
        protected Vector2 _Size;
        protected Rectangle _Bounds { get { return new Rectangle((int)_Position.X, (int)_Position.Y, (int)_Size.X, (int)_Size.Y); } }
        protected string _Shader = "";

        public Vector2 Position { get { return _Position; } set { _Position = value; } }
        public Vector2 Size { get { return _Size; } set { _Size = value; } }

        public Texture2d(Vector2 position, Vector2 size, string asset)
        {
            _Position = position;
            _Size = size;
            _Asset = asset;
            _EffectType = EffectTypes.NoShader;
        }

        public void SetShader(string asset, EffectTypes effectType)
        {
            _EffectType = effectType;
            _Shader = asset;
        }
        public Texture2d(Vector2 position, Vector2 size, string asset, EffectTypes effectType)
        {
            _Position = position;
            _Size = size;
            _Asset = asset;
            _EffectType = effectType;
        }
        public void SetDisplacementTexture(string newAsset)
        {
            _DisplacementAsset = newAsset;
        }
        public void Draw(GameTime gameTime)
        {
            switch (_EffectType)
            {
                case EffectTypes.NoShader:
                    _SpriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Deferred, SaveStateMode.SaveState);
                   
                    _SpriteBatch.Draw(
                        _Texture,
                        _Bounds,
                        Color.White
                    );

                    _SpriteBatch.End();
                    break;

                case EffectTypes.Displacement:
                    Shader shader = ShaderManager.Instance.GetShader(_Shader);

                    shader.Effect.Begin();
                    _SpriteBatch.Begin(
                        SpriteBlendMode.AlphaBlend,
                        SpriteSortMode.Immediate,
                        SaveStateMode.None
                    );

                    shader.Effect.Parameters["DisplacementScroll"].SetValue(
                        MoveInCircle(gameTime, 0.1f)
                    );
                    
                    GameEngine.Instance.Device.Textures[1] = _DisplacementTexture;

                    shader.Effect.CurrentTechnique.Passes[0].Begin();

                    _SpriteBatch.Draw(
                        _Texture,
                        _Bounds,
                        Color.White
                    );

                    _SpriteBatch.End();
                    shader.Effect.CurrentTechnique.Passes[0].End();
                    shader.Effect.End();
                    break;
            }
        }
        private Vector2 MoveInCircle(GameTime gameTime, float speed)
        {
            double time = gameTime.TotalGameTime.TotalSeconds * speed;

            float x = (float)Math.Cos(time);
            float y = (float)Math.Sin(time);

            return new Vector2(x, y);
        }
        private Vector2 MoveInCircle(GameTime gameTime, Texture2D texture, float speed)
        {
            Viewport viewport = GameEngine.Instance.Device.Viewport;

            float x = (viewport.Width - texture.Width) / 2;
            float y = (viewport.Height - texture.Height) / 2;

            return MoveInCircle(gameTime, speed) * 128 + new Vector2(x, y);
        }

        public virtual void LoadContent()
        {
            _Texture = ResourceManager.Instance.LoadContent<Texture2D>(_Asset);
            _SpriteBatch = new SpriteBatch(GameEngine.Instance.Device);

            if (_EffectType == EffectTypes.Displacement)
            {
                _DisplacementTexture = ResourceManager.Instance.LoadContent<Texture2D>(_DisplacementAsset);
            }
        }
    }

    public enum EffectTypes
    {
        NoShader,
        Displacement
    }
}
